package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.utils.Helper;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.BaseTournamentMapper;
import com.tencentcloudapi.common.AbstractModel;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.live.v20180801.LiveClient;
import com.tencentcloudapi.live.v20180801.models.*;
import com.tencentcloudapi.mps.v20190612.MpsClient;
import com.tencentcloudapi.mps.v20190612.models.*;
import com.tencentcloudapi.vod.v20180717.VodClient;
import com.tencentcloudapi.vod.v20180717.models.LiveRealTimeClipRequest;
import com.tencentcloudapi.vod.v20180717.models.LiveRealTimeClipResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;


@Slf4j
@Service
@RequiredArgsConstructor
public class LiveService {


    private final LiveProperties liveProperties;

    private final WatermarkProperties watermarkProperties;

    private final BaseTournamentMapper baseTournamentMapper;

    private LiveClient client;

    private static final String liveEndPoint = "live.ap-guangzhou.tencentcloudapi.com";
    private static final String REGION = "ap-guangzhou";

    @PostConstruct
    public void init() {
        client  = getLiveClient();
    }

    public LiveClient getLiveClient(){
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint(liveEndPoint);
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        LiveClient client = new LiveClient(tencentCredential(), REGION, clientProfile);
        return client;
    }

    public Credential tencentCredential(){
        //id和key就是腾讯云的id和秘钥
        Credential cred = new Credential("1600034841", "99088cde8b6052a76e4864fdbb9c59934a86b98734bf2da5d24cc055060e4c51");

        return cred;
    }

    private final Log logger = LogFactory.getLog(LiveService.class);

    /**
     * 获取OBS推流码
     * @param endTime
     * @return
     */
    public LiveStreamCode getOBSCode( String streamName, LocalDateTime endTime, Integer type,Long  tournamentId) {
        String endTimeStr = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Long unixTime = Helper.getUnixTime(endTimeStr); // 获取时间戳
        // 转换为十六进制
        String txTime = Integer.toHexString(unixTime.intValue()).toUpperCase();
        // MD5加密 推流端的Secret
        String txPushSecret = Helper.getMd5(liveProperties.getPushKey() + streamName + txTime);
        // MD5加密 播放端的Secret
        String txViewSecret = Helper.getMd5(liveProperties.getViewKey() + streamName + txTime);

        String obsServer; // obs服务器
        String streamCode; // obs推流码
        String playCode;// 播放的URL码
        obsServer = "rtmp://" + liveProperties.getPushURL() +"/live/";
        BaseTournament baseTournament = baseTournamentMapper.selectById(tournamentId);
        if (Objects.nonNull(baseTournament) && Objects.equals(baseTournament.getEquipmentSwitch(),1)){
            String overlayUrl = "http://scorebar.yundongshugenmatch.cn/ScoreModel?id="+ tournamentId +"&width=1920&height=1080";
            try {
                overlayUrl = URLEncoder.encode(overlayUrl, "utf-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            streamCode = streamName + "?txSecret=" + txPushSecret + "&txTime=" + txTime + "&overlay_url=" + overlayUrl;
        }else{
            streamCode = streamName + "?txSecret=" + txPushSecret + "&txTime=" + txTime;
        }
//        playCode = "webrtc://"+ liveProperties.getViewURL() +"/live/" + streamName +
//                     "?txSecret=" + txViewSecret + "&txTime=" + txTime;
        playCode = "http://" + liveProperties.getViewURL() + "/live/"
                    + streamName + ".m3u8" + "?txSecret=" + txViewSecret + "&txTime=" + txTime;
        if(type != null && type == 2){
            // webrtc推流和播放模式 自适应码流播放
            obsServer = "webrtc://" + liveProperties.getPushURL() +"/live/";
        }
        obsServer = obsServer+streamCode;
        // 返回生成的结果
        return new LiveStreamCode(streamName,obsServer, streamCode, playCode);
    }

    public List<String> getPlayCodeList(String streamName, LocalDateTime endTime, Integer type, String[] transcodeArr) {
        String endTimeStr = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Long unixTime = Helper.getUnixTime(endTimeStr); // 获取时间戳
        // 转换为十六进制
        String txTime = Integer.toHexString(unixTime.intValue()).toUpperCase();
        String txViewSecret;
        List<String> playCodeList = new ArrayList<>();
        if(type != null && type == 1){
            // webrtc推流和播放模式 自适应码流播放
            for (String str : transcodeArr) {
                txViewSecret = Helper.getMd5(liveProperties.getViewKey() + streamName + "_" + str + txTime);
                playCodeList.add("webrtc://"+ liveProperties.getViewURL() +"/live/" + streamName +
                        "_" + str + "?txSecret=" + txViewSecret + "&txTime=" + txTime);
            }
        }else {
            // 默认推流和播放模式 自适应码流播放
            for (String str : transcodeArr) {
                txViewSecret = Helper.getMd5(liveProperties.getViewKey() + streamName + "_" + str + txTime);
                playCodeList.add("https://" + liveProperties.getViewURL() + "/live/"
                        + streamName + "_" + str + ".m3u8" + "?txSecret=" + txViewSecret + "&txTime=" + txTime);
            }
        }
        return playCodeList;
    }

    public List<String> getPlayCode(String streamName,Integer type, int visibleTime) {
        LocalDateTime endTime = LocalDateTime.now().plusMinutes(visibleTime);
        String[] strArr = {liveProperties.getFHD(), liveProperties.getHD(), liveProperties.getSD()};
        return getPlayCodeList(streamName,endTime,type,strArr);
    }

    /**
     * 直播推流断开
     *
     * @param streamName 流名称
     */
    public void dropLiveStream(String streamName) {
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DropLiveStreamRequest req = new DropLiveStreamRequest();
            req.setStreamName(streamName);
            req.setDomainName(liveProperties.getPushURL());
            req.setAppName(liveProperties.getAppName());
            // 返回的resp是一个DropLiveStreamResponse的实例，与请求对象对应
            DropLiveStreamResponse resp = client.DropLiveStream(req);
            // 输出json格式的字符串回包
            logger.error("掐断直播了..." + DropLiveStreamResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            logger.error("掐断直播异常了..." + e.toString());
        }
    }

    /**
     * 禁止直播推流
     *
     * @param streamName 流名称
     * @param seconds    禁止推流秒数
     * @param reason     禁止原因
     */
    public Object forbidLiveStream(String streamName, Integer seconds, String reason) {
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            ForbidLiveStreamRequest req = new ForbidLiveStreamRequest();
            req.setStreamName(streamName);
            req.setDomainName(liveProperties.getPushURL());
            req.setAppName(liveProperties.getAppName());
            if(seconds != null){
                String resumeTime = plusSecondsUTC(seconds); // 添加一分钟的UTC时区时间
                req.setResumeTime(resumeTime);
            }
            req.setReason(reason);
            // 返回的resp是一个DropLiveStreamResponse的实例，与请求对象对应
            ForbidLiveStreamResponse resp = client.ForbidLiveStream(req);
            logger.error("禁止直播推流..." + DropLiveStreamResponse.toJsonString(resp));
            // 输出json格式的字符串回包
            return DropLiveStreamResponse.toJsonString(resp);
        } catch (TencentCloudSDKException e) {
            logger.error("禁止直播推流异常了..." + e.toString());
            throw new RuntimeException(e);
        }
    }

    /**
     * 恢复直播推流
     * @param streamName 流名称
     */
    public Object resumeLiveStream(String streamName){
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            ResumeLiveStreamRequest req = new ResumeLiveStreamRequest();
            req.setStreamName(streamName);
            req.setDomainName(liveProperties.getPushURL());
            req.setAppName(liveProperties.getAppName());
            // 返回的resp是一个ResumeLiveStreamResponse的实例，与请求对象对应
            ResumeLiveStreamResponse resp = client.ResumeLiveStream(req);

            logger.info("恢复直播推流返回结果... " + ResumeLiveStreamResponse.toJsonString(resp));
            return ResumeLiveStreamResponse.toJsonString(resp);
        } catch (TencentCloudSDKException e) {
            logger.error("恢复直播推流出现异常... " + e.toString());
        }
        return null;
    }

    /**
     * 获取当前正在直播的流
     * @return
     */
    public String describeLiveStreamPushInfoList() {
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DescribeLiveStreamPushInfoListRequest req = new DescribeLiveStreamPushInfoListRequest();
            req.setPushDomain(liveProperties.getPushURL());
            req.setAppName(liveProperties.getAppName());

            // 返回的resp是一个DescribeLiveStreamPushInfoListResponse的实例，与请求对象对应
            DescribeLiveStreamPushInfoListResponse resp = client.DescribeLiveStreamPushInfoList(req);
            // 输出json格式的字符串回包
//            logger.info("当前正在直播的流 : " + DescribeLiveStreamPushInfoListResponse.toJsonString(resp));
            return DescribeLiveStreamPushInfoListResponse.toJsonString(resp);
        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询流状态
     * @param streamName
     * @return 1 直播中 0 未直播 -1 封禁中
     */
    public Integer describeLiveStreamState(String streamName) {
        try {
            DescribeLiveStreamStateRequest req = new DescribeLiveStreamStateRequest();
            req.setDomainName(liveProperties.getPushURL());
            req.setAppName(liveProperties.getAppName());
            req.setStreamName(streamName);

            DescribeLiveStreamStateResponse resp = client.DescribeLiveStreamState(req);
            return resp.getStreamState().equals("active") ? 1 :
                    resp.getStreamState().equals("inactive") ? 0 : -1; // 返回状态
        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取直播中的主备流
     * @param streamName
     */
    public Object describeBackupStreamList(String streamName) throws TencentCloudSDKException {
        DescribeBackupStreamListRequest req = new DescribeBackupStreamListRequest();
        req.setStreamName(streamName);
        // 返回的resp是一个DescribeBackupStreamListResponse的实例，与请求对象对应
        DescribeBackupStreamListResponse resp = client.DescribeBackupStreamList(req);
        // 输出json格式的字符串回包
        return DescribeBackupStreamListResponse.toJsonString(resp);
    }

    /**
     * 添加延时直播
     * @param streamName
     * @param time
     */
    public void addDelayLiveStream(String streamName, Integer time) {
        try {
            AddDelayLiveStreamRequest req = new AddDelayLiveStreamRequest();
            req.setAppName(liveProperties.getAppName());
            req.setDomainName(liveProperties.getPushURL());
            req.setStreamName(streamName);
            req.setDelayTime(Long.valueOf(time));
            // 返回的resp是一个AddDelayLiveStreamResponse的实例，与请求对象对应
            AddDelayLiveStreamResponse resp = client.AddDelayLiveStream(req);
            logger.info("延迟设置成功" + time + "s,返回参数为:" + resp);
        } catch (TencentCloudSDKException e) {
            logger.error("延迟直播出现问题" + e.toString());
            throw new RuntimeException(e);
        }
    }

    /**
     * 取消延迟直播
     * @param streamName
     */
    public void resumeDelayLiveStream(String streamName){
        try {
            ResumeDelayLiveStreamRequest req = new ResumeDelayLiveStreamRequest();
            req.setAppName(liveProperties.getAppName());
            req.setDomainName(liveProperties.getPushURL());
            req.setStreamName(streamName);
            ResumeDelayLiveStreamResponse resp = client.ResumeDelayLiveStream(req);
            logger.info("延迟取消成功,返回参数为:" + resp);
        } catch (TencentCloudSDKException e) {
            logger.error("取消延迟直播出现问题" + e.toString());
            throw new RuntimeException(e);
        }
    }

    /**
     * 切换直播主备流
     * @param streamName
     * @param sequence
     * @return
     * @throws TencentCloudSDKException
     */
    public Object switchBackupStream(String streamName,String sequence) {
        try {

            SwitchBackupStreamRequest req = new SwitchBackupStreamRequest();
            req.setPushDomainName(liveProperties.getPushURL());
            req.setAppName(liveProperties.getAppName());
            req.setStreamName(streamName);
            req.setUpstreamSequence(sequence);

            SwitchBackupStreamResponse resp = client.SwitchBackupStream(req);

            logger.info("返回结果: " + SwitchBackupStreamResponse.toJsonString(resp) + " 切换主备流成功...");
            return SwitchBackupStreamResponse.toJsonString(resp);
        } catch (TencentCloudSDKException e) {
            logger.error("切换主备流出错...");
            throw new RuntimeException(e);
        }
    }

//    /**
//     * 添加直播水印
//     * @param watermark
//     * @return
//     */
//    public Long addLiveWatermark(DfmUserWatermark watermark){
//        try {
//            logger.info("查看配置文件参数" + watermarkProperties.toString());
//            AddLiveWatermarkRequest req = new AddLiveWatermarkRequest();
//            req.setPictureUrl(watermark.getPic());
//
////            if(serverConfig.isDev() || serverConfig.isTesting() || serverConfig.isTest()){
////                req.setWatermarkName(watermark.getUserId() + "水印-t");
////            }else {
////                req.setWatermarkName(watermark.getUserId() + "水印");
////            }
//            // 设置默认配置文件参数
//            req.setXPosition(watermark.getxPosition());
//            req.setYPosition(watermark.getyPosition());
//            req.setWidth(watermark.getWidth());
//            req.setHeight(watermark.getHeight());
//            req.setBackgroundWidth(watermark.getBackgroundWidth());
//            req.setBackgroundHeight(watermark.getBackgroundHeight());
//
//            AddLiveWatermarkResponse resp = client.AddLiveWatermark(req);
//            return resp.getWatermarkId();
//        } catch (TencentCloudSDKException e) {
//            logger.error("创建直播水印出错...");
//            throw new RuntimeException(e);
//        }
//    }
//
//    public void updateLiveWatermark(DfmUserWatermark watermark){
//        try {
//            UpdateLiveWatermarkRequest req = new UpdateLiveWatermarkRequest();
//            req.setWatermarkId(watermark.getWatermarkId());
//            req.setPictureUrl(watermark.getPic());
//            req.setXPosition(watermark.getxPosition());
//            req.setYPosition(watermark.getyPosition());
//            req.setWidth(watermark.getWidth());
//            req.setHeight(watermark.getHeight());
//            req.setBackgroundWidth(watermark.getBackgroundWidth());
//            req.setBackgroundHeight(watermark.getBackgroundHeight());
//
//            UpdateLiveWatermarkResponse resp = client.UpdateLiveWatermark(req);
//        } catch (TencentCloudSDKException e) {
//            logger.error("修改直播水印出错...");
//            throw new RuntimeException(e);
//        }
//
//    }

    /**
     * 删除直播水印
     * @param watermarkId
     * @return
     */
    public void deleteLiveWatermark(Long watermarkId){
        try{
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(liveProperties.getSecretId(), liveProperties.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("live.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            LiveClient client = new LiveClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DeleteLiveWatermarkRequest req = new DeleteLiveWatermarkRequest();
            req.setWatermarkId(watermarkId);
            // 返回的resp是一个DeleteLiveWatermarkResponse的实例，与请求对象对应
            DeleteLiveWatermarkResponse resp = client.DeleteLiveWatermark(req);
            // 输出json格式的字符串回包
            logger.info("删除直播水印->>"+AbstractModel.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            logger.error("删除直播水印出错..."+e.getMessage());
        }
    }

    /**
     * 水印绑定直播间
     * @param streamName
     * @param watermarkId
     * @return
     */
    public Object createLiveWatermarkRule(String streamName,Long watermarkId){
        try {
            CreateLiveWatermarkRuleRequest req = new CreateLiveWatermarkRuleRequest();
            req.setDomainName(liveProperties.getPushURL());
            req.setAppName(liveProperties.getAppName());
            req.setStreamName(streamName);
            req.setTemplateId(watermarkId);
            CreateLiveWatermarkRuleResponse resp = client.CreateLiveWatermarkRule(req);
            System.out.println(CreateLiveWatermarkRuleResponse.toJsonString(resp));
            return CreateLiveWatermarkRuleResponse.toJsonString(resp);
        } catch (TencentCloudSDKException e) {
            logger.error("直播间绑定水印失败...");
            throw new RuntimeException(e);
        }
    }

    /**
     * 直播间解绑水印
     * @param streamName
     * @return
     */
    public Object deleteLiveWatermarkRule(String streamName){
        try {
            DeleteLiveWatermarkRuleRequest req = new DeleteLiveWatermarkRuleRequest();
            req.setDomainName(liveProperties.getPushURL());
            req.setAppName(liveProperties.getAppName());
            req.setStreamName(streamName);
            // 返回的resp是一个DeleteLiveWatermarkRuleResponse的实例，与请求对象对应
            DeleteLiveWatermarkRuleResponse resp = client.DeleteLiveWatermarkRule(req);
            // 输出json格式的字符串回包
            System.out.println(DeleteLiveWatermarkRuleResponse.toJsonString(resp));
            return DeleteLiveWatermarkRuleResponse.toJsonString(resp);
        } catch (TencentCloudSDKException e) {
            logger.error("直播间解绑水印失败...");
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取单个水印详情
     * @param watermarkId
     * @return
     */
    public Object describeLiveWatermark(Long watermarkId){
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DescribeLiveWatermarkRequest req = new DescribeLiveWatermarkRequest();
            req.setWatermarkId(watermarkId);
            // 返回的resp是一个DescribeLiveWatermarkResponse的实例，与请求对象对应
            DescribeLiveWatermarkResponse resp = client.DescribeLiveWatermark(req);
            return resp.getWatermark(); // 返回水印信息
        } catch (TencentCloudSDKException e) {
            logger.info("获取水印详情失败...");
            throw new RuntimeException(e);
        }
    }

    /**
     * 新增拉流转推
     * @param sourceUrl
     * @param startTime
     * @param endTime
     * @param nickname
     * @param toUrl
     * @return
     */
    public String createLivePullStreamTask(String sourceUrl,LocalDateTime startTime,
                                           LocalDateTime endTime,String nickname,String toUrl){
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            CreateLivePullStreamTaskRequest req = new CreateLivePullStreamTaskRequest();
            req.setSourceType("PullLivePushLive");

            String[] sourceUrls = {sourceUrl};
            req.setSourceUrls(sourceUrls); // 来源地址

            req.setStartTime(Helper.getUTCTime(startTime)); // 开始时间
            req.setEndTime(Helper.getUTCTime(endTime)); // 结束时间
            req.setOperator(nickname); // 作者
            req.setToUrl(toUrl); // 转推地址
            req.setDomainName("");
            req.setAppName("");
            req.setStreamName("");

            // 返回的resp是一个CreateLivePullStreamTaskResponse的实例，与请求对象对应
            CreateLivePullStreamTaskResponse resp = client.CreateLivePullStreamTask(req);
            // 输出json格式的字符串回包
            System.out.println(CreateLivePullStreamTaskResponse.toJsonString(resp));
            return resp.getTaskId();
        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 更新拉流任务
     * @param taskId
     * @param sourceUrl
     * @param nickname
     * @param startTime
     * @param endTime
     * @param toUrl
     * @return
     */
    public Object modifyLivePullStreamTask(String taskId,String nickname,String sourceUrl,
                                           LocalDateTime startTime,LocalDateTime endTime,String toUrl){
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            ModifyLivePullStreamTaskRequest req = new ModifyLivePullStreamTaskRequest();
            req.setTaskId(taskId);

            if(sourceUrl != null){
                String[] sourceUrls = {sourceUrl};
                req.setSourceUrls(sourceUrls); // 来源地址
            }

            if(startTime != null && endTime != null){
                req.setStartTime(Helper.getUTCTime(startTime)); // 开始时间
                req.setEndTime(Helper.getUTCTime(endTime)); // 结束时间
            }

            req.setOperator(nickname);
            req.setToUrl(toUrl);
            // 返回的resp是一个ModifyLivePullStreamTaskResponse的实例，与请求对象对应
            ModifyLivePullStreamTaskResponse resp = client.ModifyLivePullStreamTask(req);
            restartLivePullStreamTask(taskId,nickname); // 重启该任务
            return resp;
        } catch (TencentCloudSDKException e) {
            logger.info("更新拉流任务失败..." + e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 重启拉流任务
     * @param taskId
     * @param nickname
     */
    public void restartLivePullStreamTask(String taskId, String nickname){
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            RestartLivePullStreamTaskRequest req = new RestartLivePullStreamTaskRequest();
            req.setTaskId(taskId);
            req.setOperator(nickname);
            // 返回的resp是一个RestartLivePullStreamTaskResponse的实例，与请求对象对应
            RestartLivePullStreamTaskResponse resp = client.RestartLivePullStreamTask(req);
            logger.info("重启拉流任务返回结果..." + RestartLivePullStreamTaskResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            logger.info("重启拉流任务失败..." + e);
            throw new RuntimeException(e);
        }
    }

    public void deleteLivePullStreamTask(String taskId, String nickname){
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DeleteLivePullStreamTaskRequest req = new DeleteLivePullStreamTaskRequest();
            req.setTaskId(taskId);
            req.setOperator(nickname);
            // 返回的resp是一个DeleteLivePullStreamTaskResponse的实例，与请求对象对应
            DeleteLivePullStreamTaskResponse resp = client.DeleteLivePullStreamTask(req);
            // 输出json格式的字符串回包
            logger.info("删除拉流任务返回结果..." + RestartLivePullStreamTaskResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            logger.info("删除拉流任务失败..." + e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取推流列表数据
     * @param streamName
     * @param startTime
     * @param endTime
     * @return
     */
    public PushQualityData[] describeStreamPushInfoList(String streamName,LocalDateTime startTime,LocalDateTime endTime){
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DescribeStreamPushInfoListRequest req = new DescribeStreamPushInfoListRequest();
            req.setStreamName(streamName);
            req.setStartTime(timeToUTC(startTime));
            req.setEndTime(timeToUTC(endTime));
            // 返回的resp是一个DescribeStreamPushInfoListResponse的实例，与请求对象对应
            DescribeStreamPushInfoListResponse resp = client.DescribeStreamPushInfoList(req);
            // 输出json格式的字符串回包
            return resp.getDataInfoList();
        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }
    }

    public DayStreamPlayInfo[] describeStreamPlayInfoList(String streamName,LocalDateTime startTime,LocalDateTime endTime){
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DescribeStreamPlayInfoListRequest req = new DescribeStreamPlayInfoListRequest();
            req.setStreamName(streamName);
            req.setStartTime(timeToUTC(startTime));
            req.setEndTime(timeToUTC(endTime));
            // 返回的resp是一个DescribeStreamPlayInfoListResponse的实例，与请求对象对应
            DescribeStreamPlayInfoListResponse resp = client.DescribeStreamPlayInfoList(req);
            // 输出json格式的字符串回包
            return resp.getDataInfoList();
        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }
    }





    /**
     * 当前时间加上描述再转换为UTC时区的时间
     *
     * @param seconds 秒
     * @return 格式化后的时间
     */
    public String plusSecondsUTC(Integer seconds) {
        LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(seconds);

        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
        ZonedDateTime utcDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("UTC"));
        return utcDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"));
    }

    public String timeToUTC(LocalDateTime dateTime) {
        ZonedDateTime zonedDateTime = ZonedDateTime.of(dateTime, ZoneId.systemDefault());
        ZonedDateTime utcDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("UTC"));
        return utcDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"));
    }
    public LiveRealTimeClipResponse LiveRealTimeClip(LiveRealTimeClipRequest req) throws TencentCloudSDKException{
        req.setSkipSign(false);
        return this.internalRequest(req, "LiveRealTimeClip", LiveRealTimeClipResponse.class);
    }

    private LiveRealTimeClipResponse internalRequest(LiveRealTimeClipRequest req, String liveRealTimeClip, Class<LiveRealTimeClipResponse> liveRealTimeClipResponseClass) {
        try{
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(liveProperties.getSecretId(), liveProperties.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("vod.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            VodClient client = new VodClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象

            // 返回的resp是一个LiveRealTimeClipResponse的实例，与请求对象对应
            LiveRealTimeClipResponse resp = client.LiveRealTimeClip(req);
            // 输出json格式的字符串回包
            System.out.println(AbstractModel.toJsonString(resp));
            return resp;
        } catch (TencentCloudSDKException e) {
            System.out.println(e.toString());
        }
        return null;
    }

    public String getHighlightShot(String viewUrl, LocalDateTime beginTime, LocalDateTime endTime) {
        if (viewUrl.contains("_pow")){
            viewUrl = viewUrl.replace("_pow", "");
        }
        String endTimeStr = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Long unixTimeEnd = Helper.getUnixTime(endTimeStr); // 获取时间戳
        String beginTimeStr = beginTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Long unixTimeBegin = Helper.getUnixTime(beginTimeStr); // 获取时间戳

        String playCode =
                viewUrl + "&txTimeshift=on&tsFormat=unix&tsStart="+unixTimeBegin+"&tsEnd="+unixTimeEnd;
        // 返回生成的结果
        return playCode;
    }

//    public static void main(String[] args) {
//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//        LocalDateTime beginTime = LocalDateTime.parse("2024-05-28 16:49:44", formatter);
//        LocalDateTime endTime = LocalDateTime.parse("2024-05-28 16:49:58", formatter);
//        String obsCode = getHighlightShot("206TjSjjo", beginTime, endTime);
//        System.out.println(obsCode);
//    }

    /**
     * 获取固化视频
     */
    public ProcessMediaResponse ProcessMedia(String url) {
        try{
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(liveProperties.getSecretId(), liveProperties.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("mps.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            MpsClient client = new MpsClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            ProcessMediaRequest req = new ProcessMediaRequest();
            MediaInputInfo mediaInputInfo1 = new MediaInputInfo();
            mediaInputInfo1.setType("URL");
            UrlInputInfo urlInputInfo1 = new UrlInputInfo();
            urlInputInfo1.setUrl(url);
            mediaInputInfo1.setUrlInputInfo(urlInputInfo1);

            req.setInputInfo(mediaInputInfo1);

            TaskOutputStorage taskOutputStorage1 = new TaskOutputStorage();
            taskOutputStorage1.setType("COS");
            CosOutputStorage cosOutputStorage1 = new CosOutputStorage();
            cosOutputStorage1.setBucket("ydsg-1256672631");
            cosOutputStorage1.setRegion("ap-guangzhou");
            taskOutputStorage1.setCosOutputStorage(cosOutputStorage1);

            req.setOutputStorage(taskOutputStorage1);

            req.setOutputDir("/file/");
            req.setScheduleId(10101L);
            // 返回的resp是一个ProcessMediaResponse的实例，与请求对象对应
            ProcessMediaResponse resp = client.ProcessMedia(req);

            // 输出json格式的字符串回包
            return resp;
        } catch (TencentCloudSDKException e) {
            log.error(e.toString());
        }
        return null;
    }

    /**
     * 查看点播详情
     */
    public DescribeTaskDetailResponse DescribeTaskDetail(String taskId) {
        try{
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(liveProperties.getSecretId(), liveProperties.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("mps.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            MpsClient client = new MpsClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DescribeTaskDetailRequest req = new DescribeTaskDetailRequest();
            req.setTaskId(taskId);
            // 返回的resp是一个DescribeTaskDetailResponse的实例，与请求对象对应
            DescribeTaskDetailResponse resp = client.DescribeTaskDetail(req);
            // 输出json格式的字符串回包
            System.out.println(AbstractModel.toJsonString(resp));
            return resp;
        } catch (TencentCloudSDKException e) {
            log.error(e.toString());
        }
        return null;
    }
    /**
     *对视频进行编辑，生成一个新的视频。编辑的功能包括：
     一、**剪辑任务**：简单的视频剪辑，如剪辑、拼接等
     1. 对一个文件进行剪辑，生成一个新的视频；
     2. 对多个文件进行拼接，生成一个新的视频；
     3. 对多个文件进行剪辑，然后再拼接，生成一个新的视频。

     二、**合成任务**：通过接口描述信息，合成一个新的视频。
     1. 多轨道（视频、音频、字幕）、多类型元素（视频、图片、音频、文字、空）
     2. 图像级别：贴图、缩放、任意角度旋转、镜像等
     3. 音频级别：音量控制、淡入淡出、混音等
     4. 视频级别：转场、倍数播放、拼接、剪切、字幕、画中画、音画分离、出入场动效等
     * @param req EditMediaRequest
     * @return EditMediaResponse
     * @throws TencentCloudSDKException
     */
    public EditMediaResponse EditMedia(List<BaseLivePlayBackEven> livePlayBackEvenList,String name) throws TencentCloudSDKException {
        if (CollUtil.isEmpty(livePlayBackEvenList)){
            return null;
        }
        try {
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(liveProperties.getSecretId(), liveProperties.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("mps.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            MpsClient client = new MpsClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            EditMediaRequest req = new EditMediaRequest();
            Integer num = 0;
            EditMediaFileInfo[] editMediaFileInfos1 = new EditMediaFileInfo[livePlayBackEvenList.size()];

            for (BaseLivePlayBackEven vo:livePlayBackEvenList) {
                EditMediaFileInfo editMediaFileInfo1 = new EditMediaFileInfo();
                MediaInputInfo mediaInputInfo1 = new MediaInputInfo();
                mediaInputInfo1.setType("COS");
                CosInputInfo cosInputInfo1 = new CosInputInfo();
                cosInputInfo1.setBucket("ydsg-1256672631");
                cosInputInfo1.setRegion("ap-guangzhou");
                String replace = vo.getVideoUrl().replace("https://ydsg-1256672631.cos.ap-guangzhou.myqcloud.com", "");
                cosInputInfo1.setObject(replace);
                mediaInputInfo1.setCosInputInfo(cosInputInfo1);

                editMediaFileInfo1.setInputInfo(mediaInputInfo1);

                editMediaFileInfo1.setStartTimeOffset(0F);
                editMediaFileInfo1.setEndTimeOffset(0F);
                editMediaFileInfos1[num] = editMediaFileInfo1;
                num++;
            }

            req.setFileInfos(editMediaFileInfos1);

            TaskOutputStorage taskOutputStorage1 = new TaskOutputStorage();
            taskOutputStorage1.setType("COS");
            CosOutputStorage cosOutputStorage1 = new CosOutputStorage();
            cosOutputStorage1.setBucket("ydsg-1256672631");
            cosOutputStorage1.setRegion("ap-guangzhou");
            taskOutputStorage1.setCosOutputStorage(cosOutputStorage1);

            req.setOutputStorage(taskOutputStorage1);
            req.setOutputObjectPath("/file/all_EditMedia_"+name+".mp4");
            // 返回的resp是一个EditMediaResponse的实例，与请求对象对应
            EditMediaResponse resp = client.EditMedia(req);
            // 输出json格式的字符串回包
            System.out.println(AbstractModel.toJsonString(resp));
            return resp;
        } catch (TencentCloudSDKException e) {
            System.out.println(e.toString());
        }
        return null;

    }
    /**
     * 创建混流
     */
    public void createCommonMixStream(String streamName,Long watermarkId,Long contestWatermarkId) {
        logger.info("创建混流~");
        try{
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(liveProperties.getSecretId(), liveProperties.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("live.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            LiveClient client = new LiveClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            CreateCommonMixStreamRequest req = new CreateCommonMixStreamRequest();
            req.setMixStreamSessionId(streamName+"_room");


            CommonMixInputParam[] commonMixInputParams1 = new CommonMixInputParam[2];
            CommonMixInputParam commonMixInputParam1 = new CommonMixInputParam();
            commonMixInputParam1.setInputStreamName(streamName);
            CommonMixLayoutParams commonMixLayoutParams1 = new CommonMixLayoutParams();
            commonMixLayoutParams1.setImageLayer(1L);
            commonMixLayoutParams1.setImageHeight(0F);
            commonMixLayoutParams1.setImageWidth(0F);
            commonMixInputParam1.setLayoutParams(commonMixLayoutParams1);

            commonMixInputParams1[0] = commonMixInputParam1;

            CommonMixInputParam commonMixInputParam2 = new CommonMixInputParam();
            commonMixInputParam2.setInputStreamName(streamName);
            CommonMixLayoutParams commonMixLayoutParams2 = new CommonMixLayoutParams();
            commonMixLayoutParams2.setImageLayer(3L);
            commonMixLayoutParams2.setInputType(2L);
            commonMixLayoutParams2.setImageHeight(0.15F);
            commonMixLayoutParams2.setImageWidth(0.15F);
            commonMixLayoutParams2.setLocationX(0.83F);
            commonMixLayoutParams2.setLocationY(0.03F);
            commonMixLayoutParams2.setWatermarkId(contestWatermarkId);
            commonMixInputParam2.setLayoutParams(commonMixLayoutParams2);

            CommonMixCropParams commonMixCropParams1 = new CommonMixCropParams();
            commonMixCropParams1.setCropWidth(0F);
            commonMixCropParams1.setCropHeight(0F);
            commonMixCropParams1.setCropStartLocationX(0F);
            commonMixCropParams1.setCropStartLocationY(0F);
            commonMixInputParam2.setCropParams(commonMixCropParams1);

            commonMixInputParams1[1] = commonMixInputParam2;

            req.setInputStreamList(commonMixInputParams1);

            CommonMixOutputParams commonMixOutputParams1 = new CommonMixOutputParams();
            commonMixOutputParams1.setOutputStreamName(streamName);
            req.setOutputParams(commonMixOutputParams1);

            logger.info("创建混流入参->>>\n"+AbstractModel.toJsonString(req));
            // 返回的resp是一个CreateCommonMixStreamResponse的实例，与请求对象对应
            CreateCommonMixStreamResponse resp = client.CreateCommonMixStream(req);
            // 输出json格式的字符串回包
            System.out.println(AbstractModel.toJsonString(resp));
            logger.info("创建混流返回信息->"+AbstractModel.toJsonString(resp));

        } catch (TencentCloudSDKException e) {
            logger.info(e.toString());
        }
    }


    /**
     * 创建水印
     * @param teamOneName 主队名称
     * @param teamOneScore 主队分数
     * @param subsection 小节
     * @param teamTwoScore 客队分数
     * @param teamTwoName 客队名称
     * @param contestName 联赛名称
     * @param leftNum 主队犯规
     * @param rightNum 客队犯规
     * @return
     */
    public Long addLiveWatermark(String teamOneName, Long teamOneScore, String subsection, Long teamTwoScore, String teamTwoName, String contestName, int leftNum, int rightNum) {
        logger.info("添加水印~");
        String name = String.valueOf(System.currentTimeMillis()/ 1000);// 时间戳
        OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                .build();
        String url = "http://127.0.0.1:3000/getDrawImg?" +
                "txt1=" + teamOneName + "&txt2=" + teamOneScore + "&txt3=" + subsection + "&txt4=" + teamTwoScore + "&txt5=" + teamTwoName + "&txt6=" + contestName + "&fileId=" + name + "&leftNum=" + leftNum + "&rightNum=" + rightNum;
        Request request = new Request.Builder()
                .url(url)
                .build();
        logger.info("水印url->>"+url);
        try {
            Response response = okHttpClient.newCall(request).execute();
            String responseStr = Objects.requireNonNull(response.body()).string();
            Map<String,String> map = JSON.parseObject(responseStr, Map.class);
            logger.info("返回水印url->>"+responseStr);
            String imgUrl = map.get("imgUrl");
            logger.info("上传水印url->>"+imgUrl);
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(liveProperties.getSecretId(), liveProperties.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("live.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            LiveClient client = new LiveClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            AddLiveWatermarkRequest req = new AddLiveWatermarkRequest();
            req.setPictureUrl(imgUrl);
            req.setWatermarkName(name);
            req.setXPosition(20L);
            req.setYPosition(83L);
            req.setWidth(60L);
            req.setHeight(10L);
            logger.info("上传水印传参对象->>"+JSON.toJSONString(req));
            // 返回的resp是一个AddLiveWatermarkResponse的实例，与请求对象对应
            AddLiveWatermarkResponse resp = client.AddLiveWatermark(req);
            // 输出json格式的字符串回包
            System.out.println(AbstractModel.toJsonString(resp));
            return resp.getWatermarkId();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 取消混流
     * @param s
     */
    public void cancelCommonMixStream(String s) {
        try{
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(liveProperties.getSecretId(), liveProperties.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("live.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            LiveClient client = new LiveClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            CancelCommonMixStreamRequest req = new CancelCommonMixStreamRequest();
            req.setMixStreamSessionId(s);
            // 返回的resp是一个CancelCommonMixStreamResponse的实例，与请求对象对应
            CancelCommonMixStreamResponse resp = client.CancelCommonMixStream(req);
            // 输出json格式的字符串回包
            logger.info("取消混流->>"+AbstractModel.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            logger.info(e.toString());
        }
    }
    /**
     * 创建水印
     * @param teamOneName 主队名称
     * @param teamOneScore 主队分数
     * @param subsection 小节
     * @param teamTwoScore 客队分数
     * @param teamTwoName 客队名称
     * @param contestName 联赛名称
     * @param leftNum 主队犯规
     * @param rightNum 客队犯规
     * @return
     */
    public void updateLiveWatermark(Long watermarkId, String teamOneName, Long teamOneScore, String subsection, Long teamTwoScore, String teamTwoName, String contestName, Integer leftNum, Integer rightNum) {
        logger.info("修改水印");
        String name = String.valueOf(System.currentTimeMillis()/ 1000);// 时间戳
        OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                .build();
        String url = "http://127.0.0.1:3000/getDrawImg?" +
                "txt1=" + teamOneName + "&txt2=" + teamOneScore + "&txt3=" + subsection + "&txt4=" + teamTwoScore + "&txt5=" + teamTwoName + "&txt6=" + contestName + "&fileId=" + name + "&leftNum=" + leftNum + "&rightNum=" + rightNum;
        Request request = new Request.Builder()
                .url(url)
                .build();
        logger.info("水印url->>"+url);
        try {
            Response response = okHttpClient.newCall(request).execute();
            String responseStr = Objects.requireNonNull(response.body()).string();
            Map<String,String> map = JSON.parseObject(responseStr, Map.class);
            logger.info("返回水印url->>"+responseStr);
            String imgUrl = map.get("imgUrl");
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(liveProperties.getSecretId(), liveProperties.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("live.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            LiveClient client = new LiveClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            UpdateLiveWatermarkRequest req = new UpdateLiveWatermarkRequest();
            req.setWatermarkId(watermarkId);
            req.setPictureUrl(imgUrl);
            req.setXPosition(20L);
            req.setYPosition(83L);
            req.setWidth(60L);
            req.setHeight(10L);
            // 返回的resp是一个AddLiveWatermarkResponse的实例，与请求对象对应
            UpdateLiveWatermarkResponse resp = client.UpdateLiveWatermark(req);
            // 输出json格式的字符串回包
            logger.info("添加水印返回信息->"+AbstractModel.toJsonString(resp));
        } catch (Exception e) {
            logger.info(e.toString());
        }
    }

    public Long addContestLiveWatermark(String logo,String name) {
        try {
            logger.info("创建联赛logo水印图片>>"+logo);
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(liveProperties.getSecretId(), liveProperties.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("live.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            LiveClient client = new LiveClient(cred, "", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            AddLiveWatermarkRequest req = new AddLiveWatermarkRequest();
            req.setPictureUrl(logo);
            req.setWatermarkName( String.valueOf(System.currentTimeMillis()/ 1000));
            req.setXPosition(83L);
            req.setYPosition(3L);
            req.setWidth(15L);
            req.setHeight(15L);
            // 返回的resp是一个AddLiveWatermarkResponse的实例，与请求对象对应
            AddLiveWatermarkResponse resp = client.AddLiveWatermark(req);
            // 输出json格式的字符串回包
            logger.info("创建联赛logo水印入参>>"+AbstractModel.toJsonString(resp));
            return resp.getWatermarkId();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
